# author-wechat：findpanpan

import requests, time, hmac, hashlib
from okex.authorization import recv_window, api_secret, api_key
from okex.client import Client
import decimal, json, datetime, base64
try:
    from urllib import urlencode
# python3
except ImportError:
    from urllib.parse import urlencode


from data.runBetData import RunBetData
runbet = RunBetData()

class OkexAPI(object):

    REST_URL = "https://www.ouyi.cc"

    def __init__(self):
        self.key = api_key
        self.secret = api_secret
        self.client = Client()

    def get_ticker_price(self, market):
        path = '/api/v5/market/ticker'
        params = {"instId" : market}
        res = self.client._request_with_params('GET', path, params)
        return decimal.Decimal(res['data'][0]['last'])

    def get_ticker_24hour(self,market):
        path = '/api/v5/market/ticker'
        params = {"instId" : market}
        res = self.client._request_with_params('GET', path, params)
        last = decimal.Decimal(res['data'][0]['last'])
        open24h = decimal.Decimal(res['data'][0]['open24h'])
        ratio_24hr = decimal.Decimal((last - open24h) / open24h).quantize(decimal.Decimal('0.00'))
        return ratio_24hr

    def buy_market(self, market, quantity, cur_market_price):
        '''
            现货市价买入
        :param market:
        :param quantity:
        :return:
        '''
        path = "/api/v5/trade/order"
        params = self._spot_order(market, quantity, "buy", cur_market_price)
        print(params)
        return self.client._request_with_params('POST', path, params)

    def sell_market(self, market, quantity, cur_market_price):
        '''现货市价卖出'''
        path = "/api/v5/trade/order"
        params = self._spot_order(market, quantity, "sell", cur_market_price)
        return self.client._request_with_params('POST', path, params)

    def market_future_order(self, side, symbol, quantity, positionSide):

        ''' 合约市价单
            :param side: 做多or做空 BUY SELL
            :param symbol:币种类型。如：BTCUSDT、ETHUSDT
            :param quantity: 购买量
            :param positionSide: 双向持仓 BUY-LONG 开多 SELL-SHORT 开空
            :param price: 开仓价格
        '''
        path = "/api/v5/trade/order"
        params = self._order(symbol, quantity, side, positionSide)
        print(params)
        return self.client._request_with_params('POST', path, params)


    def get_klines(self, market, interval, limit, before = None, after = None):
        path = '/api/v5/market/candles'
        params = None
        if before is None:
            params = {"instId" : market, "interval" : interval, "limit" : limit}
        else:
            params = {"instId" : market, "limit" : limit, "interval" : interval, "before" : before, "after" : after}
        res = self.client._request_with_params('GET', path, params)
        return res['data']

    # def get_spot_trades(self, symbol):
    #     '''获取账户成交历史'''
    #     path = "%s/myTrades" % self.BASE_URL_V3
    #     params = {"symbol":symbol}
    #     time.sleep(1)
    #     return self._get(path, params).json()

    # ### --- 合约 --- ###
    # def set_leverage(self,symbol, leverage):
        
    #     ''' 调整开仓杠杆
    #         :param symbol 交易对
    #         :param leverage 杠杆倍数
    #     '''
    #     path = "%s/fapi/v1/leverage" % self.BASE_URL
    #     params = {'symbol':symbol, 'leverage': leverage}
    #     return self._post(path, params)

    # def get_positionInfo(self, symbol):
    #     '''当前持仓交易对信息'''
    #     path = "%s/fapi/v2/positionRisk" % self.FUTURE_URL
    #     params = {"symbol":symbol}
    #     time.sleep(1)
    #     return self._get(path, params)


    def limit_future_order(self, side, market, quantity, positionSide, price):

        ''' 合约限价单
            :param side: 做多or做空 BUY SELL
            :param market:币种类型。如：BTCUSDT、ETHUSDT
            :param quantity: 购买量
            :param positionSide: 双向持仓 BUY-LONG 开多 SELL-SHORT 开空
            :param price: 开仓价格
        '''
        path = "/api/v5/trade/order"
        params = self._order(market, quantity, side, positionSide, price)
        return self.client._request_with_params('POST', path, params)

    ### ----私有函数---- ###

    def _order(self, market, quantity, side, posSide, price=None):
        '''
        :param market:币种类型。如：BTCUSDT、ETHUSDT
        :param quantity: 购买量
        :param side: 订单方向，买还是卖
        :param positionSide 双向持仓
        :param price: 价格
        :return:
        '''
        params = {}

        if price is not None:
            params["type"] = "LIMIT"
            params["price"] = self._format(price)
            params["timeInForce"] = "GTC"
        else:
            params["ordType"] = "market"

        params["instId"] = market
        params["side"] = side
        params["sz"] = quantity
        params['posSide'] = posSide
        params['tdMode'] = 'isolated'
        return params

    def _spot_order(self, market, quantity, side, cur_market_price, price=None):
        '''
        :param market:币种类型。如：BTCUSDT、ETHUSDT
        :param quantity: 购买量
        :param side: 订单方向，买还是卖
        :param price: 价格
        :return:
        '''
        params = {}

        if price is not None:
            params["type"] = "LIMIT"
            params["price"] = self._format(price)
            params["timeInForce"] = "GTC"
        else:
            params["ordType"] = "market"

        params["ordType"] = "limit"
        params["instId"] = market
        params["side"] = side
        params["sz"] = str(decimal.Decimal(decimal.Decimal(quantity) / decimal.Decimal(runbet.get_spot_ratio())))
        params["px"] = str(cur_market_price)
        # params['posSide'] = 'net'
        params['tdMode'] = 'cash'

        return params

    def _get(self, path, params={}):
        params.update({"recvWindow": recv_window})
        query = urlencode(self._sign(params))
        url = "%s?%s" % (path, query)
        header = {"X-MBX-APIKEY": self.key}
        return requests.get(url, headers=header,timeout=30, verify=True).json()
        
    def _get_no_sign(self, url, path, params={}):
        query = urlencode(params)
        url = "%s?%s" % (url, query)
        header = self._header('GET', path)
        return requests.get(url, headers=header, timeout=180, verify=True).json()

    def _sign(self, params={}):
        data = params.copy()

        ts = int(1000 * time.time())
        data.update({"timestamp": ts})
        h = urlencode(data)
        b = bytearray()
        b.extend(self.secret.encode())
        signature = hmac.new(b, msg=h.encode('utf-8'), digestmod=hashlib.sha256).hexdigest()
        data.update({"signature": signature})
        return data

    def _post(self, url, path, params={}):
        # query = self._sign(params)
        query = params
        url = "%s" % (url)
        header = self._header('POST', path, json.dumps(params))
        return requests.post(url, headers=header, data=query, timeout=180, verify=True).json()

    def _header(self, method = 'GET', path = '', body = ''):
        utc = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.000Z")
        print(utc + method + path + body + self.secret)
        key = bytes(utc + method + path + body + self.secret, encoding='utf-8')
        sign = base64.b64encode(hmac.new(key, digestmod = hashlib.sha256).digest())
        print(sign)
        sign = str(sign, 'utf-8')
        print(sign)
        headers = {
            'OK-ACCESS-KEY' : self.key,
            'OK-ACCESS-SIGN' : sign,
            'OK-ACCESS-TIMESTAMP' : utc,
            'OK-ACCESS-PASSPHRASE' : 'ss120ss120',
            'Connection': 'close'
        }
        print(headers)
        
        return headers
        
    def _format(self, price):
        return "{:.8f}".format(price)

if __name__ == "__main__":
    instance = OkexAPI(api_key, api_secret)
    # print(instance.buy_limit("EOSUSDT",5,2))